using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class AesGcmHelper
{
    // 非ce长度必须为12字节（96位），与前端保持一致
    private const int NonceSize = 12;

    /// <summary>
    /// 加密JSON数据并保存为文件
    /// </summary>
    /// <param name="jsonData">要加密的JSON字符串</param>
    /// <param name="key">256位（32字节）密钥</param>
    /// <param name="filePath">保存文件路径</param>
    public static void EncryptAndSave(string jsonData, byte[] key, string filePath)
    {
        // 验证密钥长度
        if (key.Length != 32)
            throw new ArgumentException("密钥必须是32字节（256位）", nameof(key));

        // 生成随机nonce
        byte[] nonce = new byte[NonceSize];
        RandomNumberGenerator.Fill(nonce);

        // 转换数据为字节数组
        byte[] dataBytes = Encoding.UTF8.GetBytes(jsonData);

        // 加密
        using (AesGcm aes = new AesGcm(key))
        {
            byte[] ciphertext = new byte[dataBytes.Length];
            byte[] tag = new byte[AesGcm.TagByteSizes.MaxSize]; // 16字节标签

            aes.Encrypt(nonce, dataBytes, ciphertext, tag);

            // 组合nonce、加密数据和标签（格式：nonce + ciphertext + tag）
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            using (BinaryWriter writer = new BinaryWriter(fs))
            {
                writer.Write(nonce);
                writer.Write(ciphertext);
                writer.Write(tag);
            }
        }
    }

    /// <summary>
    /// 从文件读取并解密数据
    /// </summary>
    /// <param name="key">256位（32字节）密钥</param>
    /// <param name="filePath">文件路径</param>
    /// <returns>解密后的JSON字符串</returns>
    public static string LoadAndDecrypt(byte[] key, string filePath)
    {
        // 验证密钥长度
        if (key.Length != 32)
            throw new ArgumentException("密钥必须是32字节（256位）", nameof(key));

        // 读取文件内容
        byte[] fileData = File.ReadAllBytes(filePath);

        // 解析nonce、加密数据和标签
        using (MemoryStream ms = new MemoryStream(fileData))
        using (BinaryReader reader = new BinaryReader(ms))
        {
            byte[] nonce = reader.ReadBytes(NonceSize);
            byte[] ciphertext = reader.ReadBytes(fileData.Length - NonceSize - AesGcm.TagByteSizes.MaxSize);
            byte[] tag = reader.ReadBytes(AesGcm.TagByteSizes.MaxSize);

            // 解密
            using (AesGcm aes = new AesGcm(key))
            {
                byte[] plaintext = new byte[ciphertext.Length];
                aes.Decrypt(nonce, ciphertext, tag, plaintext);

                return Encoding.UTF8.GetString(plaintext);
            }
        }
    }

    /// <summary>
    /// 将前端存储的密钥字符串转换为字节数组
    /// </summary>
    /// <param name="keyString">前端生成的密钥字符串</param>
    /// <returns>32字节密钥</returns>
    public static byte[] ConvertKeyStringToBytes(string keyString)
    {
        if (string.IsNullOrEmpty(keyString))
            throw new ArgumentNullException(nameof(keyString));

        byte[] key = new byte[keyString.Length];
        for (int i = 0; i < keyString.Length; i++)
        {
            key[i] = (byte)keyString[i];
        }

        if (key.Length != 32)
            throw new ArgumentException("无效的密钥长度，必须是32字节", nameof(keyString));

        return key;
    }

    /// <summary>
    /// 生成新的256位AES密钥（与前端格式兼容）
    /// </summary>
    /// <returns>密钥字节数组和可存储的字符串表示</returns>
    public static (byte[] KeyBytes, string KeyString) GenerateNewKey()
    {
        byte[] key = new byte[32];
        RandomNumberGenerator.Fill(key);

        // 转换为与前端兼容的字符串格式
        char[] keyChars = new char[32];
        for (int i = 0; i < 32; i++)
        {
            keyChars[i] = (char)key[i];
        }

        return (key, new string(keyChars));
    }
}